package com.wstuo.common.config.category.dao;

import com.wstuo.common.config.category.dto.EventCategoryDTO;
import com.wstuo.common.config.category.entity.EventCategory;
import com.wstuo.common.dao.BaseDAOImplHibernate;
import com.wstuo.common.dto.PageDTO;

import java.util.List;

import org.hibernate.FetchMode;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;

/**
 * Event Category DAO Class
 * 
 * @author Jet date 2010-9-10
 */
public class EventCategoryDAO extends BaseDAOImplHibernate<EventCategory>
		implements IEventCategoryDAO {
	/**
	 * According to hql statements query data
	 */
	@SuppressWarnings("unchecked")
	public List<EventCategory> findTreeViews(String CategoryName) {
		String hql = "from EventCategory ec where ec.parentEvent IS NULL and categoryRoot = '"
				+ CategoryName + "' order by ec.eventId asc ";

		return getHibernateTemplate().find(hql);
	}

	/**
	 * 查询常用分类树
	 * 
	 * @param CategoryName
	 * @return EventCategory
	 */
	@SuppressWarnings("unchecked")
	public EventCategory findEventCategoryTree(String categoryRoot) {
		EventCategory category = null;
		final DetachedCriteria dc = DetachedCriteria
				.forClass(EventCategory.class);

		dc.createAlias("parentChildren", "children", DetachedCriteria.LEFT_JOIN);
		dc.setFetchMode("parentChildren", FetchMode.JOIN);

		dc.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
		dc.add(Restrictions.eq("categoryRoot", categoryRoot));

		List<EventCategory> list = getHibernateTemplate().findByCriteria(dc);
		if (list != null && list.size() > 0)
			category = list.get(0);
		return category;
	}

	/**
	 * 查询常用分类树
	 * 
	 * @param parentEventId
	 * @return EventCategory
	 */
	@SuppressWarnings("unchecked")
	public EventCategory findEventCategoryTreeByParentEventId(Long parentEventId) {
		EventCategory category = null;
		final DetachedCriteria dc = DetachedCriteria
				.forClass(EventCategory.class);

		dc.createAlias("parentChildren", "children", DetachedCriteria.LEFT_JOIN);
		dc.setFetchMode("parentChildren", FetchMode.JOIN);

		dc.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
		dc.add(Restrictions.eq("eventId", parentEventId));

		List<EventCategory> list = getHibernateTemplate().findByCriteria(dc);
		if (list != null && list.size() > 0)
			category = list.get(0);
		return category;
	}

	/**
	 * 最迟的ID
	 */
	public static Long latesEventId = 0L;

	/**
	 * 初始化.
	 */
	public static void initLatesEventId(Long eventId) {
		latesEventId = eventId;
	}

	/**
	 * 累加分类ID.
	 */
	public static synchronized void increment() {
		latesEventId += 1;
	}

	/**
	 * 取得最新的ID.
	 * 
	 * @return Long
	 */
	public static synchronized Long getLatestEventId() {
		return latesEventId;
	}

	/**
	 * 取得下一个ID.
	 * 
	 * @return Long
	 */
	@SuppressWarnings("rawtypes")
	public Long getNextEventId() {

		Long v = 1L;
		final String hql = "select max(e.eventId) from EventCategory e";
		List list = getHibernateTemplate().find(hql);

		if (list != null && list.size() > 0) {

			Number n = (Number) list.get(0);
			if (n != null) {
				v = n.longValue();
			}

		}
		return v;
	}

	/**
	 * 重写SAVE方法.
	 */
	@Override
	public void save(EventCategory eventCategory) {
		if (eventCategory.getEventId() == null
				|| eventCategory.getEventId() == 0) {
			Long latesEventId = getLatestEventId();
			if (latesEventId == 0L) {
				initLatesEventId(getNextEventId());
			}
		}

		increment();// 自增1.
		if (eventCategory.getEventId() == null
				|| eventCategory.getEventId() == 0) {
			eventCategory.setEventId(getLatestEventId());
		}
		super.save(eventCategory);

	}

	/**
	 * 根据父节点查询所有子节点。
	 * 
	 * @param parentId
	 * @return EventCategory
	 */
	@SuppressWarnings("unchecked")
	public EventCategory findAllChildren(Long parentId) {
		EventCategory category = null;
		final DetachedCriteria dc = DetachedCriteria
				.forClass(EventCategory.class);
		dc.add(Restrictions.eq("eventId", parentId));
		dc.createAlias("parentChildren", "children", DetachedCriteria.LEFT_JOIN);
		dc.setFetchMode("parentChildren", FetchMode.JOIN);
		dc.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
		List<EventCategory> allChildren = getHibernateTemplate()
				.findByCriteria(dc);

		if (allChildren != null && allChildren.size() > 0) {

			category = allChildren.get(0);
		}

		return category;

	}

	/**
	 * 根据传入的编号数据查询服务目录
	 * 
	 * @param qdto
	 *            查询DTO OrganizationQueryDTO
	 * @return PageDTO 分页数据
	 */
	public PageDTO findPagerByIds(EventCategoryDTO qdto) {
		PageDTO dto = null;
		final DetachedCriteria dc = DetachedCriteria
				.forClass(EventCategory.class);
		int start = 0;
		int limit = 0;

		if ((qdto != null) && (qdto.getEventIds() != null)) {
			start = qdto.getStart();
			limit = qdto.getLimit();

			dc.add(Restrictions.in("eventId", qdto.getEventIds()));

			dto = super.findPageByCriteria(dc, start, limit);
		}

		return dto;
	}

	/**
	 * 根据父服务目录查找子服务目录.
	 * 
	 * @param parentNo
	 * @return List<EventCategory>
	 */
	@SuppressWarnings("unchecked")
	public List<EventCategory> findByParent(Long parentNo) {
		String hql = " from EventCategory ec where ec.parentEvent.eventId="
				+ parentNo;

		return super.getHibernateTemplate().find(hql);
	}

	/**
	 * 根据名称节点 查询
	 * 
	 * @param Event
	 * @return EventCategory
	 */
	public EventCategory findEventTree(String Event) {
		EventCategory category = null;
		final DetachedCriteria dc = DetachedCriteria
				.forClass(EventCategory.class);
		Event = Event.replaceAll(",", ">");
		Event = Event.replaceAll("，", ">");
		String[] EventName = Event.toString().split(">");
		int lenght = EventName.length - 1;
		for (int i = lenght; i >= 0; i--) {
			if (i == lenght) {
				dc.add(Restrictions.eq("eventName", EventName[i]));// 最低级
			} else {
				if (i == lenght - 1) {
					dc.createAlias("parentEvent", "pe" + i).add(
							Restrictions.eq("pe" + i + ".eventName",
									EventName[i]));// 倒数第二级
				} else {
					dc.createAlias("pe" + (i + 1) + ".parentEvent", "pe" + i)
							.add(Restrictions.eq("pe" + i + ".eventName",
									EventName[i]));// 倒数第N级
				}
			}
		}
		@SuppressWarnings("unchecked")
		List<EventCategory> list = getHibernateTemplate().findByCriteria(dc);
		if (list != null && list.size() > 0)
			category = list.get(0);
		return category;
	}

	/**
	 * 判断分类是否存在
	 * 
	 * @param ec
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public boolean isCategoryExisted(EventCategoryDTO ec) {

		final DetachedCriteria dc = DetachedCriteria
				.forClass(EventCategory.class);
		dc.add(Restrictions.eq("eventName", ec.getEventName()));
		dc.add(Restrictions.eq("parentEvent.id", ec.getParentEventId()));
		List<EventCategory> categories = getHibernateTemplate().findByCriteria(
				dc);

		return !categories.isEmpty();
	}

	/**
	 * 根据Path路径查询子分类
	 * 
	 * @param path
	 *            分类路径
	 * @return 返回当前路径下的所有分类
	 */
	@SuppressWarnings("unchecked")
	public List<EventCategory> findSubCategoryByPath(String path) {
		// TODO Auto-generated method stub
		final DetachedCriteria dc = DetachedCriteria
				.forClass(EventCategory.class);
		dc.add(Restrictions.like("path", path, MatchMode.START));
		return super.getHibernateTemplate().findByCriteria(dc);
	}

}
